package com.yuedou.api.service.mer.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yuedou.api.dao.mer.MerMapper;
import com.yuedou.api.dao.mer.MerUserMapper;
import com.yuedou.api.dao.platform.SplitAccountMapper;
import com.yuedou.api.dao.product.ProductOrderMapper;
import com.yuedou.api.dao.sys.SysUserMapper;
import com.yuedou.api.dao.sys.SysUserRoleMapper;
import com.yuedou.api.dao.wxuser.UserMapper;
import com.yuedou.api.entity.mer.Mer;
import com.yuedou.api.entity.mer.MerUser;
import com.yuedou.api.entity.platform.SplitAccount;
import com.yuedou.api.entity.product.Product;
import com.yuedou.api.entity.sys.SysUser;
import com.yuedou.api.entity.sys.SysUserRole;
import com.yuedou.api.entity.wxuser.User;
import com.yuedou.api.entity.wxuser.UserAddress;
import com.yuedou.api.exception.TransactionalException;
import com.yuedou.api.service.base.impl.BaseServiceImpl;
import com.yuedou.api.service.mer.MerService;
import com.yuedou.api.service.platfom.ParameterService;
import com.yuedou.api.service.platfom.SplitAccountService;
import com.yuedou.api.service.platfom.WxTemplateService;
import com.yuedou.api.service.product.ProductService;
import com.yuedou.api.util.*;
import com.yuedou.api.util.positionjudge.IsPtInPoly;
import com.yuedou.api.util.positionjudge.Point2D;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 服务商家Service业务层处理
 *
 * @author ruoyi
 * @date 2021-09-05
 */
@Service
public class MerServiceImpl extends BaseServiceImpl<MerMapper, Mer> implements MerService {

    @Resource
    private MerMapper merMapper;
    @Resource
    private MerUserMapper merUserMapper;
    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private SysUserRoleMapper sysUserRoleMapper;
    @Resource
    private ProductOrderMapper productOrderMapper;
    @Resource
    private ProductService productService;
    @Resource
    private UserMapper userMapper;
    @Resource
    private SplitAccountMapper splitAccountMapper;
    @Resource
    private WxTemplateService wxTemplateService;

    @Value("${web.imgPrefixOss}")
    private String imgPrefixOss;//图片地址

    @Value("${web.uploadPath}")
    private String uploadPath;

    @Override
    @Transactional
    public int register(Mer mer, User user, int ag_id) {
        int ret = 0;
        try{
            //
            String qrCode = "";
            String fileName = "mer_qr_" + mer.getShopNo() + ".jpg";
            String content = "https://www.sdyuedou.com/wxmini/mer/pay?no=" + mer.getShopNo();
            int upload_type = OssUtil.TYPE_MER_PHOTOS;
            System.out.println("content:  "+ content);
            String img_key = "";
            img_key = OssUtil.getUploadPrefix(upload_type) + fileName;
            QRCodeUtilEx.createQrCodeImg(content, mer.getShopName(), null, uploadPath + "/" + img_key, true,fileName,upload_type);
            qrCode = img_key;
            mer.setQrCode(qrCode);
//            mer.setAgId(0);
//            if(ag_id != user.getId().intValue()){
//            }
            mer.setAgId(ag_id);

            ret = merMapper.insert(mer);
            if(ret <= 0){
                throw new TransactionalException("merMapper insert error");
            }

            QueryWrapper<SysUser> qw = new QueryWrapper<>();
            qw.eq("user_name",mer.getTelphone());
            qw.last("limit 1");
            SysUser sysUser = sysUserMapper.selectOne(qw);
            if(sysUser == null){
                sysUser = new SysUser();
                sysUser.setRoleId(5);//商家管理员用户
                sysUser.setUserType(4);//商家用户
                sysUser.setUserName(mer.getTelphone());
                sysUser.setPassword(SecurityUtils.encryptPassword("123456"));
                sysUser.setMerId(mer.getId());
                sysUser.setNickName(mer.getLeaderName());
                sysUser.setPhoneNum(mer.getTelphone());
                sysUser.setSex("1");
                sysUser.setStatus("1");// 未审核通过 不能登录
                sysUser.setDelFlag("0");
                sysUser.setCreateTime(new Date());
                ret = sysUserMapper.insert(sysUser);
                if(ret <= 0){
                    throw new TransactionalException("merUserMapper insert error");
                }
            }

            if(sysUser.getUserId() == null || sysUser.getUserId() == 0){
                user.setSysUserId(sysUser.getUserId());
                ret = userMapper.updateById(user);
                if(ret <= 0){
                    throw new TransactionalException("sysUserRoleMapper insert error");
                }
            }

            QueryWrapper<SysUserRole> qwRole = new QueryWrapper<>();
            qwRole.eq("user_id",sysUser.getUserId());
            qwRole.eq("role_id",5);
            qwRole.last("limit 1");
            SysUserRole sysUserRole = sysUserRoleMapper.selectOne(qwRole);
            if(sysUserRole == null){
                sysUserRole = new SysUserRole();
                sysUserRole.setUserId(sysUser.getUserId());
                sysUserRole.setRoleId(5);
                ret = sysUserRoleMapper.insert(sysUserRole);
                if(ret <= 0){
                    throw new TransactionalException("sysUserRoleMapper insert error");
                }
            }

            SplitAccount splitAccount = new SplitAccount();
            splitAccount.setAccountType(3);
            splitAccount.setUserId(user.getId());
            splitAccount.setAccountId(mer.getId());
            splitAccount.setSplitMoney(new BigDecimal(0));
            splitAccount.setFreezen(new BigDecimal(0));
            splitAccount.setChargerMoney(new BigDecimal(0));
            splitAccount.setGoldenMoney(0L);
            splitAccount.setChargerMoney(new BigDecimal(0));
            splitAccount.setVipAccountMoney(new BigDecimal(0));
            ret = splitAccountMapper.insert(splitAccount);
            if(ret <= 0){
                throw new TransactionalException("merMapper insert error");
            }

            MerUser merUser = new MerUser();
            merUser.setUserId(user.getId());
            merUser.setCreateTime(new Date());
            merUser.setMerId(mer.getId());
            merUser.setSysUserId(sysUser.getUserId());
            merUser.setNickName(user.getNickName());
            merUser.setUserType(0);
            merUser.setState(0);
            merUser.setIsAdmin(1);
            ret = merUserMapper.insert(merUser);
            if(ret <= 0){
                throw new TransactionalException("merUserMapper insert error");
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new TransactionalException("mer.register system error");
        }
        return ret;
    }

    @Override
    public List<Mer> selectByState(Integer userId,Integer state,Integer cate_id,Integer cate_child_id,
                                   String keyword,int shop_type, String sort, Integer offset, Integer pageSize,double longitude,double latitude) {
        User user = userMapper.selectById(userId);
        List<Mer> list = merMapper.selectByState(user.getCity(),state,cate_id,cate_child_id,shop_type,keyword,offset,pageSize,longitude,latitude);
        if(list != null &&list.size() > 0){
            for(Mer mer : list){
                mer = getReturn(mer);
            }
        }
        return list;
    }

    @Override
    public List<Mer> selectBySection(Integer cate_child_id, Integer offset, Integer pageSize, double longitude, double latitude) {
        List<Mer> list = merMapper.selectBySection(cate_child_id,offset,pageSize,longitude,latitude);
        if(list != null &&list.size() > 0){
            for(Mer mer : list){
                mer = getReturn(mer);
            }
        }
        return list;
    }

    @Override
    public List<Mer> getListBySearch(Integer userId,String keyword,int shop_type, int pageIndex, int pageSize, double longitude,double latitude) {
        QueryWrapper<Mer> qw = new QueryWrapper<>();
        if(StrUtil.isNotEmpty(keyword)){
            qw.like("shop_name",keyword).or().like("key_word",keyword);
        }

        User user = userMapper.selectById(userId);
        int offset = (pageIndex - 1) * pageSize;
        List<Mer> list = merMapper.selectByState(user.getCity(),0,null,null,shop_type,keyword,offset,pageSize,longitude,latitude);
        for (Mer mer: list) {
            mer = getReturn(mer);
        }

        return list;
    }

    @Override
    public Map<String, Object> getWalletDaysData(Integer userId, Integer merId) {
        Map<String, Object> map = new HashMap<>();
        List<String> days = DateUtil.getDaysBetween(6,"yyyy-MM-dd");
        List<Double> totalPrice = new ArrayList<>();
        for (String day : days){
            Map<String,Object> mapParam = new HashMap<>();
            if(merId != null){
                mapParam.put("merId",merId);
            }
            mapParam.put("userId",userId);
            mapParam.put("beginTime",day + " 00:00:00");
            mapParam.put("endTime",day + " 23:59:59");
        }
        List<String> daysShow = DateUtil.getDaysBetween(6,"MM-dd");
        map.put("days",daysShow);
        map.put("totalPrices",totalPrice);

        return map;
    }

    @Override
    public Mer getMerByUserIdUnCheck(int user_id) {
        QueryWrapper<MerUser> qw = new QueryWrapper<>();
        qw.eq("user_id",user_id);
        List<MerUser> merUsers = merUserMapper.selectList(qw);
        if(CollUtil.isNotEmpty(merUsers)){
            for (MerUser merUser : merUsers){
                Mer mer = merMapper.selectById(merUser.getMerId());
                if(mer!=null){
                    //返回未审核的商家
                    if(mer.getCheckState() == 0){
                        return mer;
                    }
                }
            }
        }
        return null;
    }

    @Override
    public List<Mer> selectMyList(Integer user_id, Integer shop_type, Integer offset, Integer pageSize) {
        return merMapper.selectMyList(user_id,shop_type,offset,pageSize);
    }

    @Override
    public int selectMyMerCount(int user_id,int shop_type) {
        return merMapper.selectMyMerCount(user_id,shop_type);
    }


    @Override
    public Mer getLocationInfo(Mer mer) {
        boolean latitudeFlag = !mer.getLatitude().equals(BigDecimal.ZERO) && !mer.getLongitude().equals(BigDecimal.ZERO);
        if (latitudeFlag) {
            JSONObject locationInfo = BaiduMapUtils.getLocationInfo(mer.getLatitude().toString(), mer.getLongitude().toString());
            int status = locationInfo.getInt("status");
            if (status != 0) {
                return mer;
            }
            String province = locationInfo.getJSONObject("result").getJSONObject("addressComponent").getStr("province");
            String city = locationInfo.getJSONObject("result").getJSONObject("addressComponent").getStr("city");
            String district = locationInfo.getJSONObject("result").getJSONObject("addressComponent").getStr("district");
            mer.setProvName(province);
            mer.setCityName(city);
        }
        return mer;
    }

    @Override
    public boolean isInPoly(Mer mer, UserAddress userAddress) {
        boolean bl = false;
        if(StrUtil.isNotEmpty(mer.getPoints())){
            if(userAddress!= null){
                Point2D point2D = new Point2D(userAddress.getLng(),userAddress.getLat());
                bl = judge(point2D, JSONUtil.parseArray(mer.getPoints()));
                if(bl){
                    return bl;
                }
            }
        }
        return false;
    }

    private boolean judge(Point2D point2D, JSONArray jsonArray) {
        JSONObject jsonObject;
        List<Point2D> list = new ArrayList<>();
        Point2D aa;
        for (int i = 0; i < jsonArray.size(); i++) {
            jsonObject = JSONUtil.parseObj(jsonArray.get(i));
            aa = new Point2D(new BigDecimal(jsonObject.get("lng").toString()), new BigDecimal(jsonObject.get("lat").toString()));
            list.add(aa);
        }
        return IsPtInPoly.isPtInPoly(point2D, list);
    }


    private Mer getReturn(Mer mer){
        if(mer.getShopLogo() != null && !mer.getShopLogo().equals("")){
            mer.setShopLogo(imgPrefixOss + mer.getShopLogo());
        }
        mer.setDistance(mer.getDistance() + "km");

        List<Product> products = productService.queryProductList(mer.getId(),0);
        mer.setProducts(products);
        mer.setProductCount(products.size());

//        String[] ids = StringUtil.StrT0List(mer.getKeyWord(),",");
//        String[] type_names = new String[ids.length];
//        if(ids.length > 0){
//            int i = 0;
//            for (String id : ids){
//                ProductType type = productTypeDao.selectById(Integer.parseInt(id));
//                if(type!=null){
//                    type_names[i] = type.getTypeName();
//                }
//                i++;
//            }
//        }
//        mer.setKeywords(type_names);
        return mer;
    }
}
